home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Delphi Programmer's Power Pack
/
Delphi Volume 1.iso
/
e_to_l
/
heaptrac
/
heaptrac.exe
/
HEAPTRAC.INT
< prev
next >
Wrap
Text File
|
1996-04-10
|
7KB
|
209 lines
{
// HeapTrace
// Dynamic memory debugging for Borland Delphi.
//
// ⌐ 1996, Modelistica, Caracas. All rights reserved
// 73000.1064@compuserve.com
}
unit HeapTrac;
{ Tracing module }
interface
uses
SysUtils;
{$i HTCRight.pas }
type
TMemSize = Longint;
PMemSize = ^TMemSize;
TMemTime = Longint; { miliseconds }
type
{ tracing options }
THeapTraceOption = (
htoLogAlloc, { log allocations }
htoLogFree, { log deallocations }
htoLogResize, { log resizes }
htoLogErrors, { log errors }
htoRaiseOnErrors, { generate exceptions }
htoIgnoreZeroNil, { ignored GetMem(p, 0) and FreeMem(nil, N) errors }
htoProfiling, { create an in memory log }
htoCheckForLeaks, { check for unfreed blocks at shutdown }
htoConfigDialog, { launch configuration dialog at startup }
htoProfileDialog, { launch memory profile dialog at shutdown }
htoEraseOldLog
);
THeapTraceOptions = set of THeapTraceOption;
const
htoFullTrace = [htoLogAlloc..htoLogErrors];
{ these are the events that HeapTrace watches }
type
THeapTraceEvent = (
hteInternalError,
hteAllocated,
hteFreed,
hteResized,
hteFreeInvalid,
hteOverrun,
hteInvalid,
hteNotFreed,
hteFreeNil,
hteInvalidSize,
hteSizeIsZero,
hteOutOfMemory,
hteFakeOutOfMemory
);
THeapTraceRaisableEvent = hteFreeInvalid..hteInvalidSize;
const
HeapTraceRaisableEvents = [Low(THeapTraceRaisableEvent)..High(THeapTraceRaisableEvent)];
const
HTEventText : array[THeapTraceEvent] of PChar = (
{hteInternalError} 'Errror !!',
{hteAllocated} 'Allocated ',
{hteFreed} 'Freed ',
{hteResized} 'Resized ',
{hteFreeInvalid} 'Free Invalid !!',
{hteOverrun} 'Overrun !!',
{hteInvalid} 'Invalid !!',
{hteNotFreed} 'Not Freed !!',
{hteFreeNil} 'Free Nil !!',
{hteInvalidSize} 'Invalid Size !!',
{hteSizeIsZero} 'Size is Zero !!',
{hteOutOfMemory} 'Out of Memory !!',
{hteFakeOutOfMemory} 'Fake No Memory!!'
);
type
TAllocation = class
public
function MemPtr :Pointer; virtual; export;
function MemSize :TMemSize; virtual; export;
function WhereCreated :Pointer; virtual; export;
function WhenCreated :TMemTime; virtual; export;
function WhereFreed :Pointer; virtual; export;
function WhenFreed :TMemTime; virtual; export;
function LifeTime :TMemTime; virtual; export;
function Valid :Boolean; virtual; export;
function ObjectClass :TClass; virtual; export;
function Options :THeapTraceOptions; virtual; export;
function Freed :Boolean; virtual; export;
function Next :TAllocation; virtual; export;
end;
function HeapTraceIniFileName :string;
type
{ exceptions raised by this HeapTrace are never freed }
EHeapTrace = class(Exception)
constructor Create;
destructor Destroy; override; { do nothing }
destructor Kill; { real destructor }
procedure FreeInstance; override;
end;
{ these are exceptions raised by HeapTrace }
EHeapTraceInvalid = class(EHeapTrace);
EHeapTraceNil = class(EHeapTrace);
EHeapTraceInvalidSize = class(EHeapTrace);
EHeapTraceFreeInvalid = class(EHeapTrace);
EHeapTraceNotFreed = class(EHeapTrace);
EHeapTraceOverrun = class(EHeapTrace);
EHeapTraceSizeIsZero = class(EHeapTrace);
EHeapTraceTooLarge = class(EHeapTrace);
EHeapTraceInternalError = class(EHeapTrace);
EHeapTraceInvalidLogProc = class(EHeapTrace);
EHTAllocationChainTooLong= class(EHeapTrace);
{ raised when HeapTrace simulates an Out of Memory condition }
EHTSimulatedOutOfMemory = class(EOutOfMemory);
{ setting/getting options }
function HeapTraceOptions :THeapTraceOptions;
procedure SetHeapTraceOptions(Value :THeapTraceOptions);
procedure ChangeHeapTraceOptions(Value :THeapTraceOptions; Enable :Boolean);
{ logging }
function HeapTraceDefaultLogFileName :string;
procedure HTDefaultLog(const Msg :string);
procedure HTDefaultLogMem(Mem :Pointer; Size :TMemSize; C :TClass; Addr :Pointer; Event :THeapTraceEvent);
procedure HTDefaultLogAlloc(a :TAllocation; Addr :Pointer; Event :THeapTraceEvent);
const
{ Log is used by LogMem for final output }
Log :procedure(const Msg :string)
= HTDefaultLog;
LogMem :procedure(Mem :Pointer; Size :TMemSize; C :TClass; Addr :Pointer; Event :THeapTraceEvent)
= HTDefaultLogMem;
{ by default, LogAlloc directs it's output to LogMem }
LogAlloc :procedure(a :TAllocation; Addr :Pointer; Event :THeapTraceEvent)
= HTDefaultLogAlloc;
{ traced-heap information routines }
function TracedMemSize(Mem :Pointer):TMemSize;
function TracedMemoryValid(Mem :Pointer; Size :TMemSize):Boolean;
{ simluating out of memory conditions }
function HeapTraceAvailableMemory :TMemSize;
procedure SetHeapTraceAvailableMemory(NewSize :TMemSize);
function HeapTraceAllocatedMemory :TMemSize;
function HeapTraceMaxAllocatedMemory :TMemSize;
{ the garbage character is used to erase unused memory }
function HeapTraceGarbageChar :Char;
procedure SetHeapTraceGarbageChar(Value :Char);
{ hook to perform actions after HeapTrace has shut down }
type
THTShutDownProc = procedure;
procedure HeapTraceOnShutdownDo(Proc: THTShutDownProc);
{ check the heap for blocks that were not freed }
function HeapTraceAllocationChain :TAllocation;
procedure HeapTraceCheckForMemoryLeaks;
procedure HeapTraceClearAllocationChain;
{ The declarations here on should not be of interest to
most users. They are low level stuff useful only to
developers building enhancements to HeapTrace }
function HeapTraceActive :Boolean;
{ a safe way to test for an object's type }
function SafeIsOper(P :Pointer; C : TClass) : Boolean;
function SafeCast(P : Pointer; C : TClass) : Pointer;
function SafeClassType(P :Pointer) :TClass;
function SafeClassParent(C :TClass) :TClass;
function SafeInstanceSize(P :Pointer):TMemSize;
function SafeConvertAddr(Address: Pointer): Pointer;
function ConvertExceutableAddr(Addr :Pointer):Pointer;
function CallerAddr :Pointer;
function CallersCallerAddr :Pointer;
function AddressAtIPOffset(Offset :Integer):Pointer;
function MemSizeToStr(Size :Double):string;
function StrToMemSize(s:string):TMemSize;
type
PtrToLong = Longint;
LongToPtr = Pointer;
PPointer = ^Pointer;
TMemEvent = procedure (Mem :Pointer; Size :TMemSize; C :TClass; Addr :Pointer; Event :THeapTraceEvent);
TAllocEvent = procedure (a :TAllocation; Addr :Pointer; Event :THeapTraceEvent);
function VerMinor :Integer;
function VerMajor :Integer;
function VerDot :Integer;
function VerName :PChar;
implementation
end.